﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using HtmlAgilityPack;
using Wulong.Phone.Dianping.Constants;
using Wulong.Phone.Dianping.Models;

namespace Wulong.Phone.Dianping.Services
{
    public class ReviewService
    {
        private static readonly string BaseUrl = CommonConstants.MobileHomePage;
        public static IObservable<Review> ObservableReview(
            string merchantId, 
            string cityCode, 
            int page)
        {
            var format = BaseUrl + "/reviewlist.aspx?psid={0}&c={1}&pg={2}";
            var url = string.Format(format, merchantId, cityCode, page);
            var queryUrl = new Uri(url);//YqlHelper.HtmlQuery(url, "//div[@class='dp']");
            return from request in Observable.Return((HttpWebRequest)WebRequest.Create(queryUrl))
                   from response in Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)()
                   from item in GetReviewItem(response.GetResponseStream()).ToObservable(Scheduler.ThreadPool)
                   .ObserveOn(Scheduler.ThreadPool)
                   select item;
        }

        private static IEnumerable<Review> GetReviewItem(Stream stream)
        {
            var html = new HtmlDocument();
            html.Load(stream);
            var items = html.DocumentNode.Descendants("div")
                .Where(x => x.HasAttributes && x.Attributes[0].Value == "dp");
            foreach (var item in items)
            {
                var review = new Review();
                var firstOrDefault = item.Descendants("li").FirstOrDefault();
                if (firstOrDefault != null)
                    review.Author = firstOrDefault.InnerText;
                var lastOrDefault = item.Descendants("li").LastOrDefault();
                if (lastOrDefault != null)
                    review.PublishDate = lastOrDefault.InnerText;
                var orDefault = item.Descendants("p").FirstOrDefault();
                if (orDefault != null)
                    review.BriefReview = orDefault.InnerText.Replace("全文", "").Trim();
                var htmlNode = item.Descendants("a").FirstOrDefault();
                if (htmlNode != null)
                    review.FullReviewLink = BaseUrl + "/" + htmlNode.GetAttributeValue("href", "");
                yield return review;
            }
        }

        public static IObservable<string> ObservableFullReview(string url)
        {
            //var xpath = "//div[@class='dp']/p";
            var queryUrl = new Uri(url);//YqlHelper.HtmlQuery(url, xpath);
            return from request in Observable.Return((HttpWebRequest)WebRequest.Create(queryUrl))
                   from response in Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)()
                   from item in GetFullReview(response.GetResponseStream()).ToObservable(Scheduler.ThreadPool)
                   .ObserveOn(Scheduler.ThreadPool)
                   select item;
        }

        private static IEnumerable<string> GetFullReview(Stream stream)
        {
            var html = new HtmlDocument();
            html.Load(stream);
            var items = html.DocumentNode.Descendants("p").FirstOrDefault();
            if (items != null) yield return items.InnerText.Trim();
        }
    }
}
